package com.jwiki.app.rpcui.menu.setup;

import java.io.IOException;
import java.util.Properties;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;

import com.jwiki.app.rpcui.config.Configurations;
import com.jwiki.app.rpcui.util.SwtUtils;

public class SettingDialog extends Dialog {

    protected Object result;
    protected Shell shellSetting;
    private Text txtName;
    private Text txtLogger;
    private Text txtAddress;
    private Text txtRegTimeout;
    private Combo cmbCheck;
    private Spinner spnRetries;
    private Text txtRefTimeout;

    private Spinner spnRecursiveTimes;
    private Text txtIncludeClass;
    private Text txtExcludeClass;

    /**
     * Create the dialog.
     * @param parent
     * @param style
     */
    public SettingDialog(Shell parent, int style) {
        super(parent, style | SwtUtils.DIALOG_RESIZE);
    }

    /**
     * Open the dialog.
     * @return the result
     * @throws IOException
     */
    public Object open() throws IOException {
        createContents();
        SwtUtils.centerDialog(shellSetting, getParent());
        initDubboProperty();
        shellSetting.open();
        shellSetting.layout();
        Display display = getParent().getDisplay();
        while (!shellSetting.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        return result;
    }

    /**
     * Create contents of the dialog.
     */
    private void createContents() {
        shellSetting = new Shell(getParent(), getStyle());
        shellSetting.setImages(Configurations.DEFAULT_ICON_IMAGES);
        shellSetting.setSize(356, 418);
        shellSetting.setText("Settings");
        GridLayout gl_shellSetting = new GridLayout(1, false);
        shellSetting.setLayout(gl_shellSetting);

        TabFolder tabFolder = new TabFolder(shellSetting, SWT.NONE);
        tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

        TabItem tbtmConnection = new TabItem(tabFolder, SWT.NONE);
        tbtmConnection.setText("Connection");

        TabItem tbtmGeneration = new TabItem(tabFolder, SWT.NONE);
        tbtmGeneration.setText("Generation");

        Composite compGeneration = new Composite(tabFolder, SWT.NONE);
        tbtmGeneration.setControl(compGeneration);
        compGeneration.setLayout(new GridLayout(2, false));

        Group grpParameter = new Group(compGeneration, SWT.NONE);
        grpParameter.setLayout(new GridLayout(2, false));
        grpParameter.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
        grpParameter.setText("Parameter");
        grpParameter.setBounds(0, 0, 70, 84);

        Label lblRecursiveTimes = new Label(grpParameter, SWT.NONE);
        lblRecursiveTimes.setSize(100, 17);
        lblRecursiveTimes.setText("Recursive Times :");

        spnRecursiveTimes = new Spinner(grpParameter, SWT.BORDER);
        spnRecursiveTimes.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        spnRecursiveTimes.setSize(147, 23);
        spnRecursiveTimes.setMaximum(10);
        spnRecursiveTimes.setMinimum(1);
        spnRecursiveTimes.setSelection(3);

        Group grpInterface = new Group(compGeneration, SWT.NONE);
        grpInterface.setLayout(new GridLayout(1, false));
        grpInterface.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
        grpInterface.setText("Interface");

        Label lblNote = new Label(grpInterface, SWT.WRAP);
        lblNote.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
        lblNote.setText("Note: Use ant path as matching class path, multiple ant paths separated by comma.");

        Label lblIncludeInterfaceClass = new Label(grpInterface, SWT.NONE);
        lblIncludeInterfaceClass.setSize(134, 17);
        lblIncludeInterfaceClass.setText("Include Class :");

        txtIncludeClass = new Text(grpInterface, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL);
        GridData gd_txtIncludeClass = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
        gd_txtIncludeClass.heightHint = 52;
        txtIncludeClass.setLayoutData(gd_txtIncludeClass);

        Label lblExcludeClass = new Label(grpInterface, SWT.NONE);
        lblExcludeClass.setText("Exclude Class :");

        txtExcludeClass = new Text(grpInterface, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL);
        GridData gd_txtExcludeClass = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
        gd_txtExcludeClass.heightHint = 52;
        txtExcludeClass.setLayoutData(gd_txtExcludeClass);

        Composite composite = new Composite(tabFolder, SWT.NONE);
        tbtmConnection.setControl(composite);
        composite.setLayout(new GridLayout(1, false));

        Group grpApplication = new Group(composite, SWT.NONE);
        grpApplication.setLayout(new GridLayout(2, false));
        GridData gd_grpApplication = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
        gd_grpApplication.heightHint = 65;
        grpApplication.setLayoutData(gd_grpApplication);
        grpApplication.setText("Application");

        Label lblName = new Label(grpApplication, SWT.NONE);
        lblName.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblName.setText("Name :");

        txtName = new Text(grpApplication, SWT.BORDER);
        txtName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        Label lblLogger = new Label(grpApplication, SWT.NONE);
        lblLogger.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblLogger.setText(" Logger :");

        txtLogger = new Text(grpApplication, SWT.BORDER | SWT.READ_ONLY);
        txtLogger.setText("slf4j");
        txtLogger.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        Group grpRegistry = new Group(composite, SWT.NONE);
        grpRegistry.setText("Registry");
        grpRegistry.setLayout(new GridLayout(2, false));
        GridData gd_grpRegistry = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
        gd_grpRegistry.heightHint = 93;
        grpRegistry.setLayoutData(gd_grpRegistry);

        Label lblAddress = new Label(grpRegistry, SWT.NONE);
        lblAddress.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblAddress.setText("Address :");

        txtAddress = new Text(grpRegistry, SWT.BORDER);
        txtAddress.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        Label lblTimeout = new Label(grpRegistry, SWT.NONE);
        lblTimeout.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblTimeout.setText("Timeout :");

        txtRegTimeout = new Text(grpRegistry, SWT.BORDER);
        txtRegTimeout.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        Label lblCheck = new Label(grpRegistry, SWT.NONE);
        lblCheck.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblCheck.setText("Check :");

        cmbCheck = new Combo(grpRegistry, SWT.READ_ONLY);
        cmbCheck.setItems(new String[] {"false", "true"});
        cmbCheck.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        cmbCheck.select(0);

        Group grpReference = new Group(composite, SWT.NONE);
        grpReference.setLayout(new GridLayout(2, false));
        grpReference.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        grpReference.setText("Reference");

        Label lblTimeout_1 = new Label(grpReference, SWT.NONE);
        lblTimeout_1.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblTimeout_1.setText("Timeout :");

        txtRefTimeout = new Text(grpReference, SWT.BORDER);
        txtRefTimeout.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        Label lblRetries = new Label(grpReference, SWT.NONE);
        lblRetries.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblRetries.setText("  Retries :");

        spnRetries = new Spinner(grpReference, SWT.BORDER);
        spnRetries.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        Composite compAction = new Composite(shellSetting, SWT.NONE);
        compAction.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));
        GridLayout gl_compAction = new GridLayout(1, false);
        gl_compAction.marginHeight = 0;
        gl_compAction.marginWidth = 0;
        compAction.setLayout(gl_compAction);

        Composite compRightAction = new Composite(compAction, SWT.NONE);
        compRightAction.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));

        Button btnCancel = new Button(compRightAction, SWT.NONE);
        btnCancel.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                shellSetting.close();
                shellSetting.dispose();
            }
        });
        btnCancel.setBounds(86, 0, 80, 27);
        btnCancel.setText("Close");

        Button btnSave = new Button(compRightAction, SWT.NONE);
        btnSave.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                try {
                    Properties currentProperty = Configurations.getCurrentProperty();

                    currentProperty.setProperty("dubbo.name", txtName.getText());
                    currentProperty.setProperty("dubbo.address", txtAddress.getText());
                    currentProperty.setProperty("dubbo.regTimeout", txtRegTimeout.getText());
                    currentProperty.setProperty("dubbo.check", cmbCheck.getText());
                    currentProperty.setProperty("dubbo.retries", spnRetries.getText());
                    currentProperty.setProperty("dubbo.refTimeout", txtRefTimeout.getText());

                    currentProperty.setProperty("app.recursiveTimes", spnRecursiveTimes.getText());
                    currentProperty.setProperty("app.includeClass", txtIncludeClass.getText());
                    currentProperty.setProperty("app.excludeClass", txtExcludeClass.getText());

                    Configurations.setCurrentProperty(currentProperty);
                    shellSetting.close();
                    shellSetting.dispose();
                    MessageDialog.openInformation(getParent(), "Information", "Save properties of application success!");
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
        btnSave.setBounds(0, 0, 80, 27);
        btnSave.setText("Save");
        // add enabled listener of save button
        SwtUtils.addRequiredInputListener(composite.getChildren(), new Control[] { btnSave });
    }

    private void initDubboProperty() throws IOException {
        Properties currentProperty = Configurations.getCurrentProperty();
        // connection
        txtName.setText(currentProperty.getProperty("dubbo.name"));
        txtLogger.setText(currentProperty.getProperty("dubbo.logger"));
        txtAddress.setText(currentProperty.getProperty("dubbo.address"));
        txtRegTimeout.setText(currentProperty.getProperty("dubbo.regTimeout"));
        cmbCheck.setText(currentProperty.getProperty("dubbo.check"));
        spnRetries.setSelection(Integer.valueOf(currentProperty.getProperty("dubbo.retries")));
        txtRefTimeout.setText(currentProperty.getProperty("dubbo.refTimeout"));
        // operation
        spnRecursiveTimes.setSelection(Integer.valueOf(currentProperty.getProperty("app.recursiveTimes")));
        txtIncludeClass.setText(currentProperty.getProperty("app.includeClass"));
        txtExcludeClass.setText(currentProperty.getProperty("app.excludeClass"));
    }
}
